package com.deloitte.util;

/**
 * This class contains static methods that perform common operations on strings.
 * 
 */
public abstract class StringUtilities {

	/**
	 * This method safely trims a string by checking to see if it is null first.
	 * 
	 * @param inString String to be trimmed
	 * @param nullValue String to be returned if inString is null. If null, returns an empty string.
	 * @return String trimmed or empty (never null).
	 */
	public static String trimSafely(String inString, String nullValue) {
		String result = null;

		if (inString != null) {
			if (inString.length() > 0) {
				result = inString.trim();
			}
			else // For efficiency, don't bother
			{
				result = inString;
			}
		}
		else // Handle null case
		{
			if (nullValue != null) {
				result = nullValue;
			}
			else {
				result = "";
			}
		}

		return result;
	}

	/**
	 * Padding left for an integer with some specific format (For example 5012
	 * will be 005012 after format)
	 * 
	 * @param length Total length after padding
	 * @param number Input number that needs to be padded
	 * @param format Format to follow for padding.
	 * @return The padded string.
	 */
	public static String leftPad(int length, int number, String format) {
		String pattern = "%" + format + length + "d";
		return String.format(pattern, number);
	}

	/**
	 * Add zeroes as left padding for an integer
	 * 
	 * @param length Total length after padding
	 * @param number Input number that needs to be padded
	 * @return The padded String
	 * @see StringUtilities#leftPad(int, int, String)
	 */
	public static String leftZeroPad(int length, int number) {
		String pattern = "%0" + length + "d";
		return String.format(pattern, number);
	}
	
	/**
	 * Right adjust a string field and insert a fill character for leading blanks.
	 * @param inputString String
	 * @param length int
	 * @param fillCharacter char
	 * @return String (right adjusted input String)
	 */
	public static String rightAdjustString(String inputString, int length, char fillCharacter)
	{
		char[] rightAdjustedValue = new char[length];
		int startMove = 0;
		int outOffset = 0;
		int inOffset = 0;
		
		if (isEmpty(inputString)) {
			outOffset = length - 1;
		}
		else {

			// Locate the first non-blank at the start of the input string
			for (startMove = 0;(startMove < inputString.length()) && (inputString.charAt(startMove) == ' '); startMove++);

			// Locate the first non-blank at the end of the input string
			for (inOffset = inputString.length() - 1;(inOffset >= 0) && (inputString.charAt(inOffset) == ' '); inOffset--);

			// Move the input string to the output area
			for (outOffset = length - 1;(outOffset >= 0) && (inOffset >= startMove); outOffset--, inOffset--)
				rightAdjustedValue[outOffset] = inputString.charAt(inOffset);
		}

		// Fill out the front with the fill character
		for (; outOffset >= 0; outOffset--)
			rightAdjustedValue[outOffset] = fillCharacter;

		return new String(rightAdjustedValue);
	}
	
	/**
	 * Right adjust a string field and insert a fill character for leading blanks..
	 * @param inputString String
	 * @param length int 
	 * @return String (right adjusted input String)
	 */
	public static String rightAdjustString(String inputString, int length)
	{
		char[] rightAdjustedValue = new char[length];
		int startMove;
		int outOffset;
		int inOffset;
		// Locate the first non-blank at the start of the input string
		for (startMove = 0;(startMove < inputString.length()) && (inputString.charAt(startMove) == ' '); startMove++);

		// Locate the first non-blank at the end of the input string
		for (inOffset = inputString.length() - 1;(inOffset >= 0) && (inputString.charAt(inOffset) == ' '); inOffset--);

		// Move the input string to the output area
		for (outOffset = length - 1;(outOffset >= 0) && (inOffset >= startMove); outOffset--, inOffset--)
			rightAdjustedValue[outOffset] = inputString.charAt(inOffset);

		// Fill out the front with blanks
		for (; outOffset >= 0; outOffset--)
			rightAdjustedValue[outOffset] = ' ';

		return new String(rightAdjustedValue);
	}

	/**
	 * Checks if a string is null or empty
	 * 
	 * @param str The string to check.
	 * @return True if the string is empty. False if not.
	 */
	public static boolean isEmpty(String str) {
		if (str == null || str.trim().length() == 0) {
			return true;
		}
		return false;
	}
	
	/**
	 * Checks if a char is empty
	 * 
	 * @param chr The char to check.
	 * @return True if the char is empty. False if not.
	 */
	public static boolean isEmpty(char chr) {
		return Character.isWhitespace(chr);
	}
	
	/**
	 * Appends two strings separated  by delimiter
	 * @param arg0 The first string to append
	 * @param arg1 The string to append after the delimiter
	 * @param delimiter the delimiter between arg0 and arg1
	 * @return A String containing arg0+delimiter+arg1
	 */
	public static String appendStringsByDelimiter(String arg0,String arg1,String delimiter)
	{
		String str = "";
		StringBuffer sb = null;
		/*
		 * create string buffer instance and append arg0 if it is not empty
		 */
		if(!StringUtilities.isEmpty(arg0)){
			sb = new StringBuffer();
			sb.append(arg0);
		}
		/*
		 * create string buffer instance if arg0 is empty 
		 * If arg0 is not empty then append '.' to the end of it and append arg1
		 */
		if(!StringUtilities.isEmpty(arg1)){
			if(sb == null){
				sb = new StringBuffer();
			}
			else{
				sb.append(delimiter);
			}
			sb.append(arg1);	
		}
		if( sb != null ){
			str = sb.toString();
		}
		
		return str;
	}
	
	/**
	 * Returns char value from a string if it is of length 1 else returns blank char
	 * 
	 * @param inputStr the input string to get char value
	 * @return returns char value for the string if it's length is one
	 */
	public static char getCharFromString(String inputStr){
		char charValue = ' ';
		if(!isEmpty(inputStr) && inputStr.length() == 1){
			charValue =  inputStr.charAt(0);
		}
		return charValue;
	}

	
	/**
	 * Method to check for the existence of all numeric characters in a string.
	 * @param inputStr - string to test.
	 * @return true if all numeric. 
	 */
	public static boolean isNumeric(String inputStr) {

		boolean allNumeric = false;

		if (inputStr != null && inputStr.length() > 0) {
			
			allNumeric = true;
			
			for (int c = 0; c < inputStr.length(); c++) {
				if(!Character.isDigit(inputStr.charAt(c))) {
					allNumeric = false;
					break;
				}
			}
			
		}

		return allNumeric;
	}
	
	/**
	 * Method to check if two char values are equal or not
	 * @param arg0 - first char to compare
	 * @param arg1 - second char to compare
	 * @return true if both are same 
	 */
	public static boolean isEqualTo(char arg0,char arg1) {
		
		Character char1 = new Character(arg0);
		Character char2 = new Character(arg1);
		
		return ( char1.compareTo(char2) == 0 );
	}

	/**
	 * Method to remove the front leading zero's
	 * 
	 * @param str
	 *            - for which leading zero's needs to be removed
	 * @return String - String with no front zero's
	 */
	public static String removeLeadingZeros(String str) {
		String string = "";
		if (!StringUtilities.isEmpty(str)) {
			char[] chars = str.toCharArray();
			int index = 0;
			for (; index < str.length(); index++) {
				if (chars[index] != '0') {
					break;
				}
			}
			string = (index == 0) ? str : str.substring(index);
		}
		return string;
	}
	
	/**
	 * This method safely gets a substring from a string.
	 * 
	 * @param fullString The longer string from which to take a sub string
	 * @param beginIndex The beginning position in fullString to start the sub string
	 * @param endIndex The ending position in fullString to end the sub string
	 * @return the sub string or an empty string
	 */
	public static String getSubstring(String fullString, int beginIndex, int endIndex) {
		String subString = "";
		
		if (!isEmpty(fullString))
		{
			if (beginIndex >= 0 && beginIndex < fullString.length()) {
				if (endIndex > beginIndex && endIndex < fullString.length()) {
					subString = fullString.substring(beginIndex, endIndex);
				}
			}
		}
		return subString;
	}
	
	/**
	 * This method safely splits a String to an array of Strings.
	 * <p>
	 * Each of the string elements in the array has maximum length <b>fixedLingth</b> . 
	 * 
	 * @param fullString - the input String need to Split  
	 * @param fixedLingth - the fixed length for each string element 
	 * @return - An array of String each with maximum length <b>fixedLingth</b>.
	 */
	public static String[] getFixedLengthStringArray(String fullString,int fixedLingth){
		String[] strArray = null;
		if(!isEmpty(fullString)){
			/*
			 * Define regular expression to split the String input
			 */
			String regexp = "(?<=\\G.{"+fixedLingth+"})"; 
			/*
			 * split the input string
			 */
			strArray = fullString.split(regexp);
		}
		return strArray;
	}
	
	/**
	 * This method used to replace a message with place holders
	 * <p>
	 * Replace the place holders by the input argument
	 * 
	 * @param message The message to be replaced
	 * @param args the values for the place holder to replace
	 * @return - The message after replacement
	 */
	public static String replaceMessageWithPlaceHolder(String message,Object... args){
		return String.format(message,args);
	}
	
	/**
	 * This method used to compare between  two String arguments
	 * <p>
	 * @param arg0 - the first argument 
	 * @param arg1 - the second argument
	 * @return - Returns a negative integer, zero, or a positive integer as this <b>arg0</b> 
	 * is less than,equal to, or greater than <b>arg1</b>
	 */
	public static int compareTo(String arg0,String arg1){
		int difference = 0;
		
		if( arg0 != null){
			difference = arg0.compareTo(arg1);
		}
		else if(arg1 != null){
			difference = arg1.compareTo(arg0);
		}
		return difference;
	}
	
	
}
